package com.jt.shiro;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Shiro的配置文件
 */
@Configuration
public class ShiroConfig {

  @Bean
  public DefaultKaptcha producer() {
    Properties properties = new Properties();
    properties.put(Constants.KAPTCHA_BORDER, "no");
    properties.put(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
    properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "5");
    properties.put(Constants.KAPTCHA_IMAGE_HEIGHT, "36");
    properties.put(Constants.KAPTCHA_IMAGE_WIDTH, "116");
    properties.put(Constants.KAPTCHA_NOISE_COLOR, "blue");
    properties.put(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "28");
    Config config = new Config(properties);
    DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
    defaultKaptcha.setConfig(config);
    return defaultKaptcha;
  }

  @Bean("sessionManager")
  public SessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    // 设置session过期时间为1小时(单位：毫秒)，默认为30分钟
    sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);
    sessionManager.setSessionValidationSchedulerEnabled(true);
    sessionManager.setSessionIdUrlRewritingEnabled(false);
    return sessionManager;
  }

  @Bean("securityManager")
  public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(userRealm);
    securityManager.setSessionManager(sessionManager);

    return securityManager;
  }

  @Bean("shiroFilter")
  public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
    shiroFilter.setSecurityManager(securityManager);
    shiroFilter.setLoginUrl("/html/login.html");
    shiroFilter.setUnauthorizedUrl("/");

    Map<String, String> filterMap = new LinkedHashMap<>();
    filterMap.put("/js/**", "anon");
    filterMap.put("/api/**", "anon");
    filterMap.put("/images/**", "anon");
    filterMap.put("/css/**", "anon");
    filterMap.put("/lib/**", "anon");
    filterMap.put("/index.php", "anon");
    filterMap.put("/index.html", "anon");
    filterMap.put("/templates/index.html", "anon");
    filterMap.put("/admin/sys/login.do", "anon");
    filterMap.put("/admin/sys/logout.do","anon");
    filterMap.put("/html/bodyTab.js", "anon");
    filterMap.put("/html/login.js", "anon");
    filterMap.put("/html/common.js", "anon");
    filterMap.put("/html/login.html", "anon");
    filterMap.put("/favicon.png", "anon");
    filterMap.put("/favicon.icon", "anon");
    filterMap.put("/admin/sys//captcha.jpg", "anon");
    filterMap.put("/**", "authc");
    shiroFilter.setFilterChainDefinitionMap(filterMap);
    return shiroFilter;
  }

  @Bean("lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }

  @Bean
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
    proxyCreator.setProxyTargetClass(true);
    return proxyCreator;
  }

  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
      SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
    advisor.setSecurityManager(securityManager);
    return advisor;
  }
}
